# -*- coding: utf-8 -*-
import urllib

from asgiref.sync import sync_to_async
from channels.db import database_sync_to_async
from channels.generic.websocket import AsyncJsonWebsocketConsumer, AsyncWebsocketConsumer
import json
from application import settings
from dvadmin.system.models import MessageCenter
from scheduling.dag.graph import Node, Edge, Graph
from scheduling.dag.executer import CVExecuter
from scheduling.paradag import dag_run, SequentialProcessor
import asyncio
from datasource.views.container import gen_display, gen_display_camera
import cv2
import time
from datasource.camera import BaseCamera

send_dict = {}

# 发送消息结构体
def message(sender, msg_type, msg):
    text = {
        'sender': sender,
        'contentType': msg_type,
        'content': msg,
    }
    return text

#异步获取消息中心的目标用户
@database_sync_to_async
def _get_message_center_instance(message_id):
    _MessageCenter = MessageCenter.objects.filter(id=message_id).values_list('target_user',flat=True)
    if _MessageCenter:
        return _MessageCenter
    else:
        return []


def request_data(scope):
    query_string = scope.get('query_string', b'').decode('utf-8')
    qs = urllib.parse.parse_qs(query_string)
    return qs

async def executeDAG(data, ws):
    nodes_data = json.loads(data["nodes"])
    edges_data = json.loads(data["edges"])
    print(f"✅ 转换完成，nodes: {nodes_data}, edges: {edges_data}")

    nodes_map = {}
    edges = []
    for n in nodes_data:
        if 'isTrue' in n:
            node = Node(n['id'], n['name'], n['params'], n['isTrue'])
        else:
            node = Node(n['id'], n['name'], n['params'], True)
        nodes_map[n['id']] = node
    for e in edges_data:
        edges.append(Edge(e['source'], e['target']))
    graph = Graph(nodes_map, edges)
    if graph.validateGraph() == False:
        loop = asyncio.get_event_loop()
        task = loop.create_task(self.notifier.send_json(message('system', 'ERROR', f'非法的DAG图')))
        await task
        return
    await dag_run(graph.graph, processor=SequentialProcessor(), executor=CVExecuter(notifier=ws))

class DvadminWebSocket(AsyncJsonWebsocketConsumer):
    async def connect(self):
        await self.accept()
        await self.send_json(message('system', 'INFO', '成功连接流程通知接口'))

    async def disconnect(self, close_code):
        # 删除 send_dict 中对应的信息
        print("连接关闭")
        await self.close(close_code)


    async def receive(self, text_data=None, byte_text_data=None):
        print(f"textdata测试：{text_data}")
        try:
            text_data_json = json.loads(text_data)
        except Exception as e:
            print('数据无法被json格式化', e)
            await self.disconnect(400)
        else:
            if text_data_json['type'] == 'execute':
                await self.send_json(message('system', 'INFO', '执行算法'))
                # await executeDAG(text_data_json['data'], self)
                try:
                    flag = False
                    nodes_data = json.loads(text_data_json['data']['nodes'])
                    for item in nodes_data:
                        if item["name"] == "img_src" and item["params"]["img_src_type"] == "视频源":
                            rtsp = 'rtsp://admin:NEU12345678@192.168.31.106:554'
                            # camera = cv2.VideoCapture(rtsp)
                            camera = cv2.VideoCapture(0)
                            screen_type = int(item["params"]["screen_type"])
                            interval = int(item["params"]["interval"])
                            total = int(item["params"]["total"])
                            screenparams={'screentype':screen_type, 'interval':interval, 'total':total}
                            flag = True
                    if flag:
                        screenparams = {'screentype': 0, 'interval': 1, 'total': 100}
                        for img in gen_display_camera(camera=camera, screenparams=screenparams):
                            src_img = f'media/temp/video_origin_{str(time.time())}.png'
                            cv2.imwrite(src_img, img)
                            for item in nodes_data:
                                if item["name"] == "img_src":
                                    item["params"]["img"] = src_img
                            text_data_json['data']['nodes'] = json.dumps(nodes_data)
                            print(f"text_data_json 测试: {text_data_json['data']['nodes']}")
                            await executeDAG(text_data_json['data'], self)
                    else:
                        await executeDAG(text_data_json['data'], self)
                except StopIteration:
                    loop = asyncio.get_event_loop()
                    task = loop.create_task(self.notifier.send_json(message('system', 'INFO', {'node_id': item["id"], 'status': 'success','img': None, 'info':f'{vertex.opr}执行完毕'})))
                    await task
                    return
                except Exception as e:
                    # await self.send_json(message('system', 'ERROR', f'执行出错:{e}'))
                    await self.send_json(message('system', 'ERROR',{'node_id': item["id"], 'status': 'fail','img': None, 'info': f'执行出错:{e}'}))
                    return
            print('receive测试：',text_data_json)
